package com.moody.calculator;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.moody.hibernate.domain.ReportData;
import com.moody.hibernate.domain.ReportList;
import com.moody.init.ReportModelInit;
import com.moody.service.CustomerService;
import com.moody.service.impl.CustomerServiceImpl;

/*
 * Copyright ? Moody analytics   
 *
 * @Title: SmallCheck.java 
 * @Package： com.moody.calculator 
 * @author： Liu Peng
 * @Description: TODO(用一句话描述该文件做什么)    
 * @date： 2012-2-28 下午03:21:50
 * @Modified by: Liu Peng 
 * @version V1.0   
 */

public class SmallCheck {
	private static final Logger log = LoggerFactory.getLogger(EnterCheck.class);
	
	private Map<String,Double> valueMap;
	private Map<String,String> nameMap;
	private Map<String,String> checkMap;
	private List<ReportData> reportDataList = null;
	boolean isComplete;
	private List<String> resultList = new LinkedList<String>();
	
	public SmallCheck(List<ReportData> reportDataList){
		this.reportDataList = reportDataList;
		isComplete = true;
		valueMap = new HashMap<String,Double>();
		nameMap = ReportModelInit.getInstance().getDisplayNameMap();
		checkMap = new HashMap<String,String>();
		resultList = new LinkedList<String>();

		initValueMap();
		initCheckMap();
		
	}
	
	public List<String> check(){
		checkNegative();
		checkBalance();
		
		return resultList;
	}
	
	private void initValueMap(){
		if(reportDataList != null){
			for(ReportData rd : reportDataList){
//				if(rd.getItemValue() == null && isComplete){
//					isComplete = false;
//					resultList.add("报表完整性检查:报表不完整");
//				}
				valueMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}
	}
	
	//判断double类型是否为0
	public Boolean isZero(Double data){
		if(data!=null && (data >10E-6 || data <-(10E-6)))
			return false;
		else
			return true;
	}
	//判断double类型是否小于0
	public Boolean isNegative(Double data){
		if(data!=null && data <-(10E-6))
			return true;
		else
			return false;
	}

	public void checkBalance(){
		DecimalFormat df = new DecimalFormat("###,##0.00");
		Set<String> keySet = checkMap.keySet();
		for(String sumKey :keySet){
			if(!valueMap.containsKey(sumKey)) continue;
			String[] itemArray = checkMap.get(sumKey).split(",");
			double res = 0;
			for(String itemKey : itemArray){
				double value = 0;
				if(itemKey.substring(0, 1).equals("-")) value =  valueMap.get(itemKey.substring(1)) * -1;
				else {
					log.info(itemKey);
					value = valueMap.get(itemKey);
				}
				res += value; 
			}
			
			
			res = valueMap.get(sumKey) - res;
			
			BigDecimal bd = new BigDecimal(res);
			res = bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
			
			if(Math.abs(res) > 10E-6){
				String itemList = "";
				if(itemArray.length == 1){
					itemList = nameMap.get(itemArray[0]);
				}
				else{
					itemList = "(";
					for(String itemKey : itemArray){
						if(itemKey.substring(0, 1).equals("-")) {
							if(itemList.length() > 1) itemList += " -";
							itemList += " " + nameMap.get(itemKey.substring(1));
						}
						else {
							if(itemList.length() > 1) itemList += " +";
							itemList += " " + nameMap.get(itemKey);
						}
					}
					itemList += ")";
				}
				
				String title = "";
				if(sumKey.contains("BS")) title = "资产负债表：";
				else if(sumKey.contains("EIS")) title = "利润表：";
				else if(sumKey.contains("PIS")) title = "收入支出表：";
				else if(sumKey.contains("FIS")) title = "损益表：";
				else if(sumKey.contains("CF")) title = "现金流量表：";
				resultList.add(title + nameMap.get(sumKey) +" - " + itemList +" = " + df.format(res));
				
			}
		}
	}

	//资产负债表：非负数检查
	public boolean checkNegative(){
		boolean flag = true;

		Double SCF001 = valueMap.get("SCF001");//小企业：销售产品、提供劳务收到的现金
		Double SBS050 = valueMap.get("SBS050");//小企业：所有者权益（或股东权益）合计
		Double SIS002 = valueMap.get("SIS002");//小企业：减:主营业务成本
		Double SBS007 = valueMap.get("SBS007");//小企业：存货
		Double SBS044 = valueMap.get("SBS044");//小企业：负债合计
		Double SBS026 = valueMap.get("SBS026");//小企业：资产合计
		Double SBS051 = valueMap.get("SBS051");//小企业：负债和所有者权益合计
		Double S05001 = 0.0;
		if(valueMap.get("SIS002")!=null && valueMap.get("SIS006")!=null && valueMap.get("SIS007")!=null &&  valueMap.get("SIS008")!=null){
			S05001 = valueMap.get("SIS002") + valueMap.get("SIS006") + valueMap.get("SIS007") + valueMap.get("SIS008");//小企业：总成本费用=主营业务成本＋营业费用＋管理费用＋财务费用
		}
		Double S05002 = 0.0;
		if(valueMap.get("SBS027")!=null &&  valueMap.get("SBS037")!=null){
			S05002 = valueMap.get("SBS027") + valueMap.get("SBS037");//小企业：短期有息债务 = 短期借款＋一年内到期的长期债务
		}
		Double S05003 = 0.0;
		if(valueMap.get("SBS026") !=null &&  valueMap.get("SBS022")!=null){
			S05003 = valueMap.get("SBS026") - valueMap.get("SBS022");//小企业：有形资产总额＝资产总额－无形资产
		}
		Double SBS039 = valueMap.get("SBS039");//小企业：流动负债合计
		
		if(isNegative(SCF001)){
			resultList.add("现金流量表：销售产品、提供劳务收到的现金 < 0");
			flag = false;
		}
		if(isZero(SBS050)){
//			resultList.add("资产负债表：所有者权益 为零"); //被重复判断，所以此处取消提示
			flag = false;
		}
		if(isNegative(SIS002)){
			resultList.add("利润表：主营业务成本 < 0");
			flag = false;
		}
		if(isNegative(SBS007)){
			resultList.add("资产负债表：存货 < 0");
			flag = false;
		}
		if(isNegative(SBS044)){
			resultList.add("资产负债表：负债合计 < 0");
			flag = false;
		}
		
		if(isNegative(S05001)){
			resultList.add("利润表：总成本费用（主营业务成本＋营业费用＋管理费用＋财务费用） < 0");
			flag = false;
		}
		if(isNegative(S05002)){
			resultList.add("资产负债表：短期有息债务 （短期借款＋一年内到期的长期债务）  < 0");
			flag = false;
		}
		if(isNegative(S05003)){
			resultList.add("资产负债表：有形资产总额（资产总额－无形资产）  < 0");
			flag = false;
		}
		if(isNegative(SBS039)){
			resultList.add("资产负债表：流动负债合计 < 0");
			flag = false;
		}
		
		if(SBS026 != null && SBS051 != null){
			//资产 - 负债
			Double res = SBS026 - SBS051;
			BigDecimal bd = new BigDecimal(res);
			res = bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
			if(Math.abs(res) > 10E-6){
				resultList.add("资产负债表：资产总计 - 负债和所有者权益总计  = " + new DecimalFormat("###,##0.00").format(res));
				flag = false;
			}
		}
		
		
		return flag;
		
		
	}
	
//	//资产负债表：有形资产总额＝货币资金＋短期投资
//	public boolean checkPhysicalAssets(){
//		
//		Double SBS001 = valueMap.get("SBS001");//小企业：货币资金
//		Double SBS002 = valueMap.get("SBS002");//小企业：短期投资
//
//		if(SBS001 == null || SBS002 == null || valueMap.get("SBS026") == null || valueMap.get("SBS022") == null){
//			if(SBS001 == null){
//				resultList.add("资产负债表：货币资金 未填写 ");
//			}
//			if(SBS002 == null){
//				resultList.add("资产负债表：短期投资 未填写 ");
//			}
//			if(valueMap.get("SBS026") == null){
//				resultList.add("资产负债表：资产总额 未填写 ");
//			}
//			if(valueMap.get("SBS022") == null){
//				resultList.add("资产负债表：无形资产 未填写 ");
//			}
//
//			return false;
//		}
//		
//		
//		Double S05003 = valueMap.get("SBS026") - valueMap.get("SBS022");//小企业：有形资产总额＝资产总额－无形资产
//		
//		if(S05003.equals(SBS002 + SBS001))
//			return true;
//		else{
//			resultList.add("资产负债表：资产总计 - 无形资产 != 货币资金 + 短期投资 ");
//			return false;
//		}
//	}
	
	private void initCheckMap(){
		checkMap.put("SBS011", "SBS001,SBS002,SBS003,SBS004,SBS005,SBS006,SBS007,SBS008,SBS009,SBS010");
		checkMap.put("SBS014", "SBS012,SBS013");
		checkMap.put("SBS021", "SBS017,SBS018,SBS019,SBS020");
		checkMap.put("SBS025", "SBS022,SBS023,SBS024");
		checkMap.put("SBS026", "SBS011,SBS014,SBS021,SBS025");
		checkMap.put("SBS039", "SBS027,SBS028,SBS029,SBS030,SBS031,SBS032,SBS033,SBS034,SBS035,SBS036,SBS037,SBS038");
		checkMap.put("SBS043", "SBS040,SBS041,SBS042");
		checkMap.put("SBS044", "SBS039,SBS043");
		checkMap.put("SBS050", "SBS045,SBS046,SBS047,SBS048,SBS049");
		checkMap.put("SBS051", "SBS044,SBS050");

		checkMap.put("SIS004", "SIS001,-SIS002,-SIS003");
		checkMap.put("SIS009", "SIS004,SIS005,-SIS006,-SIS007,-SIS008");
		checkMap.put("SIS014", "SIS009,SIS010,SIS011,SIS012,-SIS013");
		checkMap.put("SIS016", "SIS014,-SIS015");

		checkMap.put("SCF003", "SCF001,SCF002");
		checkMap.put("SCF008", "SCF004,SCF005,SCF006,SCF007");
		checkMap.put("SCF009", "SCF003,-SCF008");
		checkMap.put("SCF014", "SCF010,SCF011,SCF012,SCF013");
		checkMap.put("SCF018", "SCF015,SCF016,SCF017");
		checkMap.put("SCF019", "SCF014,-SCF018");
		checkMap.put("SCF023", "SCF020,SCF021,SCF022");
		checkMap.put("SCF027", "SCF024,SCF025,SCF026");
		checkMap.put("SCF028", "SCF023,-SCF027");
		checkMap.put("SCF030", "SCF009,SCF019,SCF028,SCF029");
	}

}
